﻿using System;
using System.Collections.Generic;
using System.Linq;
using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
using eCommMongo.Core;
using eCommMongo.Core.Data;
using eCommMongo.Core.Domain.Customers;
using eCommMongo.Core.Domain.Posts;
using eCommMongo.Core.Domain.Tags;

namespace eCommMongo.Service.Tags
{
    public class TagService:ITagService
    {
        private IMongoRepository<Post> _statusRep;
        private IMongoRepository<Tag> _tagRep;
        private IMongoRepository<CustomerInterestedTag> _customerTagRep;
        private IMongoRepository<Customer> _customerRep;

        public TagService(IMongoRepository<Tag> tagRep, IMongoRepository<CustomerInterestedTag> customerTagRep, IMongoRepository<Post> statusRep, IMongoRepository<Customer> customerRep)
        {
            _tagRep = tagRep;
            _customerTagRep = customerTagRep;
            _statusRep = statusRep;
            _customerRep = customerRep;
        }

        public string AddTag(string tagName, string tagValue, string creatorId)
        {
            var query = from t in _tagRep.Table()
                        where t.TagName == tagName && t.TagValue == tagValue
                        select t;
            var tag = query.FirstOrDefault();
            if (tag != null)
            {
                var increment = Update.Inc("CountTaged", 1);
               _tagRep.Update(tag.Id,increment);
                return tag.Id;
            }
            else
            {
                var newTag = new Tag()
                    {
                        TagName = tagName,
                        TagValue = tagValue,
                        CreateAt = DateTime.Now,
                        Creator= new Customer(){Id= creatorId},
                        Deleted = false,
                        CountTaged = 1,
                    };

                _tagRep.Insert(newTag);
                return newTag.Id.ToString();
            }
        }

        public IList<Tag> FindTags(string term)
        {
            var query = from t in _tagRep.Table()
                       where t.TagName.Contains(term)
                       select t;
            return query.ToList();
        }

        public IPagedList<Tag> FindTags(int pageIndex, int pageSize)
        {
            var query = from c in _tagRep.Table()
                        orderby c.CountTaged descending
                        select c;
            var tempResult = new PagedList<Tag>(query, pageIndex, pageSize);

            return tempResult;
        }


        //public IList<TagIntroStatuses> FindPostsByTag(string tagId)
        //{

        //    var query = new QueryDocument { { "Tags._id", tagId } };

        //    var tagQuery= from c in _statusRep.Table(query)
        //                select c;

        //    return tagQuery.Take(3).ToList().Select(c => new TagIntroStatuses()
        //        {
        //            IntroStatus = c
        //        }).ToList();
        //}


        public void SaveInterestedTags(string customerId, IList<string> tagIdList)
        {
            var query = from c in _customerRep.Table()
                           where c.Id == customerId
                           select c;

            var customer = query.SingleOrDefault();
            if (customer != null)
            {
                var customerInterestedTag = new List<CustomerInterestedTag>();

                var index = 0;
                foreach (var tagId in tagIdList)
                {
                    var inTag = new CustomerInterestedTag()
                    {
                        Tag = new Tag{Id = tagId},
                        DisplayOrder = index++,
                        CreatedAt = DateTime.Now
                    };
                    customerInterestedTag.Add(inTag);
                }
                var update = Update<Customer>.Set(e => e.CustomerInterestedTags, customerInterestedTag);
                _customerRep.Update(customerId, update);
               
            }
          
        }

        public IList<Tag> FindInterestedTags(string customerId)
        {
            var query = from cit in _customerRep.Table()
                        where cit.Id == customerId
                        select cit;

            var cust = query.SingleOrDefault();
            var interestedTags = cust.CustomerInterestedTags;
            if (interestedTags == null)
            {
                return null;
            }
            else
            {
                var tagResult = new List<Tag>();
                foreach (var tempTag in interestedTags)
                {

                    var tag = _tagRep.GetById(tempTag.Tag.Id);
                    tagResult.Add(tag);
                }

                return tagResult;
            }
        }

        public IPagedList<Tag> FindInterestedTags(string customerId, int pageIndex, int pageSize)
        {
            var query = from cit in _customerRep.Table()
                        where cit.Id ==customerId
                        select cit;

            var cust = query.SingleOrDefault();
            var interestedTags = cust.CustomerInterestedTags;

            if (interestedTags == null)
                return null;

            var tempResult = new PagedList<CustomerInterestedTag>(interestedTags, pageIndex, pageSize);

            var tagList = tempResult.Select(c =>c.Tag).ToList();

            var tagResult = new List<Tag>();

            foreach (var tempTag in tagList)
            {

                var tag = _tagRep.GetById(tempTag.Id);
                tagResult.Add(tag);
            }

            var pagedList = new PagedList<Tag>(tagResult, pageIndex, pageSize, query.Count());
            return pagedList;
        }

        public Tag FindTagByTagName(string tagName)
        {
            var query = from t in _tagRep.Table()
                        where t.TagName == tagName
                        select t;
            return query.FirstOrDefault();
        }
    }
}